home *** CD-ROM | disk | FTP | other *** search
-
- Free Information Xchange presents:
-
- Thief v1.14 - CD crack by R!SC - 10/01/99
-
- REQUIREMENTS:
- Hex editor
- W32Dasm 8.93 !
-
- Do a full install, remove the CD, run the game. You get a standard messagebox asking you to
- insert the CD. "Missing CD"-"Please insert the CD into the CD Drive"
-
- First off, make a copy of thief.exe, load this into W32Dasm. We begin by looking through the
- string references for one of our messages. Heh, I didnt find any ref's! So we take a different
- approach. Look through the imported functions for a reference to KERNEL32.GetDriveTypeA
- (commonly used in CD checks(as you remember!)). Double click on the reference several times,
- looking at the code every time you click it. GetDriveTypeA returns a value in eax between 0 &
- 6, we are only intrested in the code that checks eax for a '5'. There is only one reference
- that does this.
-
-
- * Referenced by a CALL at Addresses:
- |:0050D773 , :0050DA5E <-- Trace the call back by double right clicking these (hit F12 to return)
- |
- :0050D720 8B442404 mov eax, dword ptr [esp+04]
- :0050D724 50 push eax <-- Points to a null-terminated string that specifies
- - the root directory of the disk to return information about.
- * Reference To: KERNEL32.GetDriveTypeA, Ord:00DFh - this mean 'C:\',0 or whatever drive letter the caller might be on...
- |
- :0050D725 FF1528315B00 Call dword ptr [005B3128]
- :0050D72B 33C9 xor ecx, ecx <-- zero ecx (ecx=32bit reg, cx=16bit reg, cl=low 8bits of cx)
- :0050D72D 83F805 cmp eax, 00000005 <-- checking for a CD-ROM
- :0050D730 0F94C1 sete cl <-- sets the byte in cl to a '01' if eax=5
- :0050D733 8BC1 mov eax, ecx <-- copies ecx into eax (what the last command did or didnt set)
- :0050D735 C3 ret <-- Return to caller
-
-
-
- Normally, in most cases I have seen, when there's a call to a CD check, there is normally a test
- and a conditional jump afterwards, the protection can be bypassed by either forcing the jump, or
- not taking the call at all. So I wanted to trace this code back to the original caller. Using
- WDasm 8.93! like I stated at the top, double right click the first caller '50D773'. This code is
- right beneath the call to GetDriveTypeA.
-
-
- * Referenced by a CALL at Addresses:
- |:0050D7FA , :0050D84D
- |
- :0050D740 8B442404 mov eax, dword ptr [esp+04]
- :0050D744 53 push ebx
- :0050D745 85C0 test eax, eax
- :0050D747 B341 mov bl, 41 <-- 'A'
- :0050D749 7444 je 0050D78F
- :0050D74B 8B4C240C mov ecx, dword ptr [esp+0C]
- :0050D74F 85C9 test ecx, ecx
- :0050D751 7410 je 0050D763
- :0050D753 0FBE00 movsx eax, byte ptr [eax]
- :0050D756 50 push eax
- :0050D757 E8D4EF0800 call 0059C730
- :0050D75C 8BD8 mov ebx, eax
- :0050D75E 83C404 add esp, 00000004
- :0050D761 FEC3 inc bl <-- go onto the next drive letter...
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:0050D751(C)
- |
- :0050D763 80FB5A cmp bl, 5A <-- 'Z'
- :0050D766 7F27 jg 0050D78F - simple routine to clear eax and ret
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:0050D784(C) <-- referenced to by itself
- |
-
- * Possible StringData Ref from Data Obj ->"D:\"
- |
- :0050D768 6808BF6000 push 0060BF08 <-- pushes the drive letter were on
- :0050D76D 881D08BF6000 mov byte ptr [0060BF08], bl <-- stores the next letter to check
- :0050D773 E8A8FFFFFF call 0050D720 <-- call to GetDriveTypeA Subroutine that brought us here
- :0050D778 83C404 add esp, 00000004 - return a 01 in eax if weve got a CD-ROM
- :0050D77B 85C0 test eax, eax
- :0050D77D 7509 jne 0050D788 <-- if eax in not equal(to 0) jump!
- :0050D77F FEC3 inc bl <-- increase the letter
- :0050D781 80FB5A cmp bl, 5A <-- compare it with 'Z'
- :0050D784 7EE2 jle 0050D768 <-- loop until we found a CD-ROM
- :0050D786 5B pop ebx - or ran out of drive letters
- :0050D787 C3 ret
-
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:0050D77D(C)
- |
-
- * Possible StringData Ref from Data Obj ->"D:\"
- |
- :0050D788 B808BF6000 mov eax, 0060BF08 <-- exit with the Drive letter of CD-Drive in eax
- :0050D78D 5B pop ebx
- :0050D78E C3 ret
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
- |:0050D749(C), :0050D766(C)
- |
- :0050D78F 33C0 xor eax, eax
- :0050D791 5B pop ebx
- :0050D792 C3 ret
-
-
- This code starts with drive letter 'A' and calls our previous subroutine to determine if were
- looking at a CD-ROM, if not it increases the letter and checks again. Anyway trace this back to
- one of its callers. Double right click '50D7FA'
-
- * Referenced by a CALL at Addresses:
- |:0050D9CA , :0050D9E1 <-- the original callers to this routine (trace these back)
- |
- :0050D7A0 81EC04010000 sub esp, 00000104
- :0050D7A6 8D442400 lea eax, dword ptr [esp]
- :0050D7AA 53 push ebx
- :0050D7AB 56 push esi
- :0050D7AC 57 push edi
- :0050D7AD 6804010000 push 00000104
- :0050D7B2 50 push eax
-
- * Possible StringData Ref from Data Obj ->"cd_path"
- |
- :0050D7B3 68C0BF6000 push 0060BFC0
- :0050D7B8 33DB xor ebx, ebx
- :0050D7BA E871B20300 call 00548A30
- :0050D7BF 83C40C add esp, 0000000C
- :0050D7C2 84C0 test al, al
- :0050D7C4 7528 jne 0050D7EE <-- this jne
- :0050D7C6 BF18516700 mov edi, 00675118
- :0050D7CB 83C9FF or ecx, FFFFFFFF
- :0050D7CE 33C0 xor eax, eax
- :0050D7D0 8D54240C lea edx, dword ptr [esp+0C]
- :0050D7D4 F2 repnz
- :0050D7D5 AE scasb
- :0050D7D6 F7D1 not ecx
- :0050D7D8 2BF9 sub edi, ecx
- :0050D7DA 8BC1 mov eax, ecx
- :0050D7DC 8BF7 mov esi, edi
- :0050D7DE 8BFA mov edi, edx
- :0050D7E0 C1E902 shr ecx, 02
- :0050D7E3 F3 repz
- :0050D7E4 A5 movsd
- :0050D7E5 8BC8 mov ecx, eax
- :0050D7E7 83E103 and ecx, 00000003
- :0050D7EA F3 repz
- :0050D7EB A4 movsb
- :0050D7EC EB05 jmp 0050D7F3 <-- this jmp
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:0050D7C4(C) <-- ref by same routine, the jne up there
- |
- :0050D7EE BB01000000 mov ebx, 00000001
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:0050D7EC(U) <-- ref by same routine, the jmp just up there.
- |
- :0050D7F3 8D4C240C lea ecx, dword ptr [esp+0C]
- :0050D7F7 6A00 push 00000000
- :0050D7F9 51 push ecx
- :0050D7FA E841FFFFFF call 0050D740 <-- Call that we traced back
- :0050D7FF 83C408 add esp, 00000008
- :0050D802 A314516700 mov dword ptr [00675114], eax <-- save varible in eax
- :0050D807 85C0 test eax, eax <-- check return value of previous call
- :0050D809 746B je 0050D876 <-- if it was zero we never found a CD-Drive
-
-
- Weve not get to the original caller to the CD-Check routine yet, so lets carry on tracing back.
- Double right click '50D9CA' at the top of this code.
-
- * Referenced by a CALL at Address:
- |:0050DAD5 <-- only one caller this time ;)
- |
- :0050D9C0 C7051451670000000000 mov dword ptr [00675114], 00000000
- :0050D9CA E8D1FDFFFF call 0050D7A0 <-- Call that we just traced back
- :0050D9CF 85C0 test eax, eax <-- check return value
- :0050D9D1 7517 jne 0050D9EA
-
- Goddamn it. Still not there yet, trace this back.
-
- * Referenced by a CALL at Address:
- |:00414FCC <-- YIPPEE! only one caller and the code is located faraway near the start of the executable
- |
- :0050DAC0 6A00 push 00000000
- :0050DAC2 6A00 push 00000000
-
- * Possible StringData Ref from Data Obj ->"only_check_path"
- |
- :0050DAC4 68E0BF6000 push 0060BFE0
- :0050DAC9 E862AF0300 call 00548A30
- :0050DACE 83C40C add esp, 0000000C
- :0050DAD1 84C0 test al, al
- :0050DAD3 7507 jne 0050DADC
- :0050DAD5 E8E6FEFFFF call 0050D9C0 <-- call we traced back
- :0050DADA EB05 jmp 0050DAE1
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:0050DAD3(C)
- |
- :0050DADC E82FFFFFFF call 0050DA10 <-- see 'ps' at the bottom of the file
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:0050DADA(U)
- |
- :0050DAE1 85C0 test eax, eax
- :0050DAE3 7405 je 0050DAEA
- :0050DAE5 E986FBFFFF jmp 0050D670
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:0050DAE3(C)
- |
- :0050DAEA 33C0 xor eax, eax
- :0050DAEC C3 ret
-
-
- OK, Trace this back to 414FCC, I think weve found what weve been looking for at last..
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
- |:00414F9B(C), :00414FBF(C)
- |
- :00414FCC E8EF8A0F00 call 0050DAC0 <-- A CALL
- :00414FD1 85C0 test eax, eax <-- A TEST
- :00414FD3 750B jne 00414FE0 <-- A CONDITIONAL JUMP
- :00414FD5 50 push eax - jump if eax not equal zero
- :00414FD6 6A01 push 00000001
- :00414FD8 E8337B1100 call 0052CB10 <-- This traces to a call to Terminate Process
- :00414FDD 83C408 add esp, 00000008 -- Which is very BAD
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:00414FD3(C)
- |
- :00414FE0 E8EB020000 call 004152D0
- :00414FE5 8D542440 lea edx, dword ptr [esp+40]
- :00414FE9 C744244003000000 mov [esp+40], 00000003
- :00414FF1 52 push edx
- :00414FF2 6A01 push 00000001
-
- OK, I(we) traced all those calls back to this one call at the start of the file, theres a
- call, a test and a conditional jump. I first decided to force the jne by changing it to a jmp.
- Saved my change to the code, and ran the game. Shit, it still asks for the CD, I clicked
- cancel, then the bloody thing loaded into the game! OK, the message box is somewhere deep
- inside of the CD-check routine. I decided to kill the call to the routine instead, so the CD is
- never checked, the message box will never be shown, and the game will work? Highlight the call
- to the check ':00414FCC E8EF8A0F00 call 0050DAC0' Write down the offset at the
- bottom of the screen, probably 0143CC, hexedit thief.exe goto 143CC and change the E8 to a B8.
- Save and run the game, it works fine now without needing the CD.
-
-
- Another tutorial comes to an end and another game has been FiX'ed!
-
- happy cracking love R!SC -- risc_1@hotmail.com
-
- PS. If you trace back the second caller to GetDriveTypeA (0050DA5E), scroll up a bit, this is
- referenced by a call at 50DADC, trace this back to routine, this one is referenced by 414FCC ;)
- three easy steps to get there, you should always follow all the routes possible and check them
- out, it pays off!
-
-
- for v1.14 - edit thief.exe at offset 143CC (hex)
- ===========================================================
- Search for: E8 EF 8A 0F 00 call 0050DAC0
- Change to : B8 -- -- -- -- mov eax, 000F8AEF (which is not 0, so the jne is always taken)
-
- cleaner crack is b801000000 mov eax, 00000001, but i think a 1 byte patch is nicer!
-
- I borrowed these off someone else and included them here. (win32api.txt)
-
- GetDriveType Return Function codes: (Donated by: +-=Riddler=-+)
-
- Value Meaning
- 0 Drive Cannot Be determined
- 1 Root Dir Does not exist
- 2 DriveRemoveable
- 3 A Fixed Disk (HardDrive)
- 4 Remote Drive(Network)
- 5 Cd-Rom Drive <-- Game crackers only intrested if return code is 05!
- 6 RamDisk
-
-
-
-